package edu.tjhsst.androidIntranet.login;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.DialogInterface.OnCancelListener;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.CompoundButton.OnCheckedChangeListener;
import edu.tjhsst.androidIntranet.R;
import edu.tjhsst.androidIntranet.db.IntranetDbAdapter;

public class IntranetLogin extends Activity {

	private static final String TAG = "IntranetLogin";
	private Button loginButton;
	private EditText username;
	private EditText password;
	private CheckBox remember;
	private CheckBox autoLogin;
	public LoginIOThread liot;
	private SharedPreferences prefs;


	@Override
	public void onCreate(Bundle savedInstanceState) {

		//Dummy Login
		//this.startActivity(new Intent(this, TaskPicker.class));

		super.onCreate(savedInstanceState);
		setContentView(R.layout.login);
		prefs = PreferenceManager.getDefaultSharedPreferences(this);
		loginButton = ((Button)findViewById(R.id.LoginButton));
		loginButton.setOnClickListener(new LoginListener());
		username = ((EditText)findViewById(R.id.Username));
		password = ((EditText)findViewById(R.id.Password));
		remember = ((CheckBox)findViewById(R.id.RememberLoginBox));
		remember.setOnCheckedChangeListener(new RememberListener());
		autoLogin = ((CheckBox)findViewById(R.id.AutoLoginBox));
		loadLogin(true);
	}

	public void onResume() {
		super.onResume();
		loadLogin(false);
	}

	/**
	 * 	Loads a saved login from our sql database (actually now it's a SharedPreferences database) and populates the username, password, and remember fields
	 */
	private void loadLogin(boolean firstLoad) {
		IntranetDbAdapter.AccountDbAdapter aDbA = IntranetDbAdapter.getAccountDbAdapter(this);
		if(prefs.getBoolean("remember_logon", false)) {
			Log.d(TAG, "Fetching old login");
			remember.setChecked(true);
			username.setText(aDbA.fetchUsername());
			password.setText(decrypt(aDbA.fetchPassword()));
			if(prefs.getBoolean("auto_logon", false)) {
				autoLogin.setChecked(true);
				if(firstLoad) {
					login();
				}
			} else {
				autoLogin.setChecked(false);
			}
			//Log.d(TAG, "Found and decrypted password: " + decrypt(aDbA.fetchPassword()));
		} else {
			remember.setChecked(false);
			Log.d(TAG, "Not fetching old login");
		}
		aDbA.close();
	}

	/**
	 * Saves the data stored in the username, password, and remember CheckBox fields to our sql database if the remember CheckBox is checked.
	 */
	protected void saveLogin() {
		IntranetDbAdapter.AccountDbAdapter aDbA = IntranetDbAdapter.getAccountDbAdapter(this);
		SharedPreferences.Editor prefsEdit = prefs.edit();
		if(remember.isChecked()) {
			//aDbA.setRemember(true);
			prefsEdit.putBoolean("remember_logon", true);
			aDbA.setUsername(username.getText().toString());
			aDbA.setPassword(encrypt(password.getText().toString()));
			if(autoLogin.isChecked()) {
				aDbA.setAutoLogin(true);
				prefsEdit.putBoolean("auto_logon", true);
			}
		} else {
			if(prefs.getBoolean("remember_logon", true)) {
				aDbA.setUsername("");
				aDbA.setPassword("");
				prefsEdit.putBoolean("auto_logon", false);
			}
			prefsEdit.putBoolean("remember_logon", false);
		}
		aDbA.close();
		prefsEdit.commit();
	}

	/**
	 * Returns an encrypted form of the passed {@link String}. It is recommended
	 * that you wrap the decrypted {@link String} multiple times (over 100) to
	 * help protect against brute force attacks. Because we don't expect someone
	 * to brute force attack our database, we'll only encrypt once, to prevent
	 * sql database browsers from revealing passwords. A salt is not used in this
	 * encryption scheme because salts are only useful when multiple passwords
	 * are stored, to protect against rainbow table attacks.
	 * 
	 * @param unencrypted
	 *            The decrypted {@link String} that you want encrypted
	 * @return The encrypted form of the String
	 */
	private String encrypt(String unencrypted) {
		int length = unencrypted.length();
		StringBuffer encrypted=new StringBuffer();
		for(int i=0; i<length; i++) {
			int rnd = (int) (Math.round(Math.random()*122)+68);
			encrypted.append((char)(unencrypted.charAt(i)+rnd));
			encrypted.append((char)(rnd));
		}
		return encrypted.toString();
	}

	/**
	 * Decrypts and returns the passed {@link String}
	 * 
	 * @param encrypted
	 *            The encrypted {@link String} to decrypt
	 * @return The decrypted String
	 */
	private String decrypt(String encrypted) {
		int length = encrypted.length();
		StringBuffer unencrypted=new StringBuffer();
		for(int i=0; i<length; i+=2) {
			unencrypted.append((char)(encrypted.charAt(i)-encrypted.charAt(i+1)));
		}
		return unencrypted.toString();
	}

	private void login() {
		ProgressDialog loginProgressDialog = ProgressDialog.show(IntranetLogin.this,
				"Please wait...", "Logging in to the Intranet...", true, true, new CancelLoginListener()); 
		liot = new LoginIOThread(IntranetLogin.this, loginProgressDialog, username.getText().toString(), password.getText().toString());
		liot.start();
	}

	private class LoginListener implements OnClickListener {

		//private static final String TAG = "LoginListener";

		@Override
		public void onClick(View v) {
			login();
		}
	}

	private class CancelLoginListener implements OnCancelListener {

		@Override
		public void onCancel(DialogInterface dialog) {
			liot.stopLoggingIn();
		}

	}

	public class RememberListener implements OnCheckedChangeListener {

		@Override
		public void onCheckedChanged(CompoundButton buttonView,
				boolean isChecked) {
			autoLogin.setEnabled(isChecked);
			if(!isChecked&&autoLogin.isChecked()) {
				autoLogin.setChecked(false);
			}
		}

	}
}